package communication;

/**
 * wait()
 * notify()
 * notifyAll()
 * 此三个方法，必须是在同步代码块或同步方法中。
 * Lock需要配合Condition实现线程间的通信。
 * 此三个方法的调用者，必须是同步监视器。
 *
 * wait() / sleep()
 * 相同点：一旦执行，当前线程会进入阻塞状态。
 * 不同点：
 * > 声明的位置：wait() :声明在Object类中 、 sleep()：声明在Thread类中，静态的。
 * > 使用场景不同：wait():只能使用在同步代码块或同步方法中 、 sleep():可以在任何需要使用的场景。
 * > 使用在同步代码块或同步方法中：wait()一旦执行，会释放同步监视器。而sleep()不会。
 *
 */
public class PrintNumber implements Runnable {
    private static int number = 1;

    @Override
    public void run() {
        while (true) {
            synchronized (this) {
                // 一旦执行此方法，就会唤醒被wait()的线程中优先级最高的那个。
                // 如果被wait()的多个线程优先级相等，则随机唤醒。
                notify();
//                this.notifyAll();

                if (number <= 100) {
                    print();
                    number++;
                    try {
                        // 线程一旦执行此方法，就进入等待状态。同时会释放对同步监视器的调用。
                        wait();
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                } else break;
            }
        }
    }

    public void print() {
        System.out.println(Thread.currentThread().getName() +
                " ---> " + number);
    }

}
